import { useState } from "@storybook/addons"
import React, { ChangeEvent, ReactElement, useEffect, KeyboardEvent } from "react"
import Input, { InputProps } from "../Input"
import Icon from "../Icon"
import userDebounce from "../../hooks/useDebounce"

interface DataSourceObject {
	value: string
}

export type DataSourceType<T extends object = {}> = T & DataSourceObject

interface AutoCompleteProps extends Omit<InputProps, "onSelect"> {
	fetchSuggestions: (keyword: string) => DataSourceType[] | Promise<DataSourceType[]>
	onSelect: (item: DataSourceType) => void
	renderOption?: (item: DataSourceType) => ReactElement
}

export const AutoComplete: React.FC<AutoCompleteProps> = props => {
	const { fetchSuggestions, onSelect, value, renderOption, ...restProps } = props

	const [inputValue, setInputValue] = useState(value as string)
	const [suggestions, setSuggestions] = useState<DataSourceType[]>([])
	const [loading, toggleLoading] = useState(false)
	const [hignLightIndex, setHignLightIndex] = useState(-1)
	const debounceValue = userDebounce(inputValue, 500)

	useEffect(() => {
		if (debounceValue) {
			const result = fetchSuggestions(debounceValue)
			if (result instanceof Promise) {
				toggleLoading(true)
				result.then(res => {
					setSuggestions(res)
					toggleLoading(false)
				})
			} else {
				setSuggestions(result)
			}
		} else {
			setSuggestions([])
		}
	}, [debounceValue, fetchSuggestions])

	const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
		switch (e.key) {
			case "up":
				break
			case "down":
				break
			case "enter":
				break
			case "esc":
				break
			default:
				break
		}
	}

	const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
		const value = e.target.value.trim()
		setInputValue(value)
	}

	const handleSelect = (item: DataSourceType) => {
		setInputValue(item.value)
		setSuggestions([])
		onSelect && onSelect(item)
	}

	const renderTemplate = (item: DataSourceType) => {
		return renderOption ? renderOption(item) : item.value
	}
	const generateDropDown = () => {
		return (
			<ul>
				{suggestions.map((item, index) => {
					return (
						<li
							key={index}
							onClick={() => {
								handleSelect(item)
							}}
						>
							{renderTemplate(item)}
						</li>
					)
				})}
			</ul>
		)
	}

	return (
		<div className="viking-auto-complete">
			<Input value={inputValue} {...restProps} onChange={handleChange} onKeyDown={handleKeyDown} />
			{loading && (
				<ul>
					<Icon icon={"spinner"} spin />
				</ul>
			)}
			{suggestions.length > 0 && generateDropDown()}
		</div>
	)
}
